package com.example.gobang.API;

import com.example.gobang.game.MatchRequest;
import com.example.gobang.game.MatchResponse;
import com.example.gobang.game.Matcher;
import com.example.gobang.game.OnlineUserManager;
import com.example.gobang.model.UserInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;


@Component
public class MatchAPI implements WebSocketHandler {

    ObjectMapper objectMapper = new ObjectMapper();

    //    获取 OnlineUserManager 对象
    @Autowired
    OnlineUserManager onlineUserManager;

    // 获取匹配器
    @Resource(name = "matcher")
    Matcher matcher;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("【MatchAPI：：handleTransportError】连接建立连接~");

        /**
         1. 首先讲 httpSession 加入到 webSocketSession
         .addInterceptors(new HttpSessionHandshakeInterceptor())
         */
        MatchResponse response = new MatchResponse();
        try {
            // 3。 验证是否多开
            UserInfo userInfo = (UserInfo) session.getAttributes().get("userInfo");
            if (onlineUserManager.getFromGameRoom(userInfo.getUserId()) != null
                    || onlineUserManager.getFromGameHall(userInfo.getUserId()) != null) {
                // 如果游戏房间或者游戏大厅中都有该session 的信息。说明都在线就无法进行登录
                response.setOk(true);
                response.setMessage("repeatConnection");
                response.setReason("当前游戏账号已在其他设备登录，请登录其他账号!");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                return;
            }

            // 3.排查其他异常情况就可以正常设置在线状态
            onlineUserManager.addGameHall(userInfo.getUserId(), session);
            System.out.println("玩家：" + userInfo.getUserName() + " 进入游戏大厅!");
        } catch (NullPointerException exception) {
//            2. 出现空指针异常， 说明获取 userInfo ， 即没有登录
            System.out.println("【afterConnectionEstablished】:: 验证到未登录！");
            // 设置响应
            response.setOk(false);
            response.setReason("你未登录， 请登录后再匹配!");
//            注意这里需要将Java 字符串转化为 JSON字符串
            String JSONString = objectMapper.writeValueAsString(response);
//            发送回客户端
            session.sendMessage(new TextMessage(JSONString));
        }

    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        // 1. 先将 JSONString 转化为 Java 对象
        String JSONString = (String) message.getPayload();
        MatchRequest request = objectMapper.readValue(JSONString, MatchRequest.class);

        //        2. 开始判断进行对应的效应
        UserInfo userInfo = (UserInfo) session.getAttributes().get("userInfo");
        MatchResponse response = new MatchResponse();
        if (request.getMessage().equals("startMatch")) {

            //   3. 加入到匹配队列
            matcher.add(userInfo);
            // 设置响应
            response.setMessage("startMatch");
            response.setOk(true);
        } else if (request.getMessage().equals("stopMatch")) {
            // 从匹配队列钟移除
            matcher.remove(userInfo);
            response.setOk(true);
            response.setMessage("stopMatch");
        } else {
            response.setOk(true);
            response.setMessage("接收到非法的请求!请联系客服。");
        }

//        3. 将响应发送回给客户端
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));

    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        System.out.println("【MatchAPI：：handleTransportError】建立连接异常!");
        try {
//            1. 先获取用户信息来校验 Session
            UserInfo userInfo = (UserInfo) session.getAttributes().get("userInfo");
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(userInfo.getUserId());
            if (tmpSession == session) {
                // 2. 如果当前需要退出的用户是在线的用户就退出游戏大厅
                onlineUserManager.exitGameHall(userInfo.getUserId());
            }
            // 3. 如果在匹配中， 那么就需要退出匹配队列
            matcher.remove(userInfo);

        } catch (NullPointerException e) {
            System.out.println("[handleTransportError]:: 用户未登录!");
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        System.out.println("【MatchAPI：：handleTransportError】连接关闭!");

        try {
            // 1. 还是先获取用户信息来校验 session
            UserInfo userInfo = (UserInfo) session.getAttributes().get("userInfo");
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(userInfo.getUserId());
            if (tmpSession == session) {
//            2. 如果当前要退出的 tmpSession 和在线的Session 是 一致的话，说明不是多开的账号
                onlineUserManager.exitGameHall(userInfo.getUserId());
            }

            // 3. 如果在匹配中， 那么就需要退出匹配队列
            matcher.remove(userInfo);
        } catch (NullPointerException e) {
            System.out.println("[afterConnectionClosed]:: 用户为登录!");
        }


        System.out.println("断开连接成功!");

    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
}
